package cn.chendd.cofig.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.HashMultimap;
import sun.security.action.GetPropertyAction;

import java.io.BufferedReader;
import java.io.StringReader;
import java.security.AccessController;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 复合body内容获取
 *
 * @author chendd
 * @date 2023/1/2 17:35
 */
public class MultipleBodyContent {

    /**
     * 从文件上传的请求体中获取上传文件的普通文本数据和上传文件名称
     * 兼容性最好
     * @param content 文件内容
     * @return 数据
     */
    @SuppressWarnings("all")
    public static String getBodyContent(String content) {
        HashMultimap<String,String> paramMap = HashMultimap.create();
        Pattern uploadFilePattern = Pattern.compile("Content-Disposition: form-data; name=\"(.*?)\"; filename=\"(.*?)\"");
        Pattern paramPattern = Pattern.compile("Content-Disposition: form-data; name=\"(.*?)\"");
        //行首 至少 6 个 - ，后续跟着 字母和数字组合的一串文本，最后有两个-或者没有
        Pattern endPattern = Pattern.compile("-{6,}\\w+[-]{0,2}");
        Matcher matcher = null;
        try (BufferedReader br = new BufferedReader(new StringReader(content))) {
            String line = null;
            StringBuilder builder = new StringBuilder();
            String key = null;
            String lineSeparator = AccessController.doPrivileged(new GetPropertyAction("line.separator"));
            boolean paramFlag = false;
            while ((line = br.readLine()) != null) {
                matcher = uploadFilePattern.matcher(line);
                //匹配到上传文件
                if (matcher.find()) {
                    paramMap.put(matcher.group(1) , String.format("《%s》" , matcher.group(2)));
                    continue;
                }
                //匹配到普通参数
                matcher = paramPattern.matcher(line);
                if (matcher.find()) {
                    key = matcher.group(1);
                    builder.setLength(0);
                    continue;
                }
                if (key != null && builder.length() == 0 && !paramFlag) {
                    paramFlag = true;
                    continue;
                }
                if (paramFlag) {
                    matcher = endPattern.matcher(line);
                    if (matcher.find()) {
                        paramMap.put(key , builder.toString());
                        key = null;
                        paramFlag = false;
                        builder.setLength(0);
                        continue;
                    }
                    if (builder.length() > 0) {
                        builder.append(AccessController.doPrivileged(new GetPropertyAction("line.separator")));
                    }
                    builder.append(line);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        JSONObject json = new JSONObject();
        for (String k : paramMap.keySet()) {
            Set<String> set = paramMap.get(k);
            if (set.size() == 1) {
                set.forEach(value -> {
                    json.put(k , value);
                });
            }
            JSONArray array = new JSONArray();
            array.addAll(set);
            json.put(k , array);
        }
        return JSONObject.toJSONString(json , true);
    }

}
